/*
**  Copyright (c) 2014 Michael Liu(michael.liu.point@gmail.com).
**
**  Project: Gateway Unified Management Platform
**  File:      wlanapifopt.c
**  Author:  Michael
**  Date:    06/27/2014
**
**  Purpose:
**    wlan ap interface method implement.
*/

/* Include files. */

#include "dpmgr.h"
#include "samgr.h"
#include "osdep.h"
#include "pfdep.h"
#include "wlanapifopt.h"

/* Macro constant definitions. */

#define WLAN_WPS_RESET_WPAPSK			"whr3aZhRLCrvieCFhmDyjhL61h5a8flL2TB9B5cCrdc7H4907l71i2AXrj5LyZa"

/* Type definitions. */

/* Local function declarations. */

static e_ret wlan_ap_if_create(tdp_if * dp_if);
static e_ret wlan_ap_if_destroy(tdp_if * dp_if);
static e_ret wlan_ap_if_enable(tdp_if * dp_if);
static e_ret wlan_ap_if_disable(tdp_if * dp_if);
static e_ret wlan_ap_if_setlinkcfg(tdp_if * dp_if, void *linkcfg, tmask * mask);
static e_ret wlan_ap_if_link(tdp_if * dp_if);
static e_ret wlan_ap_if_unlink(tdp_if * dp_if);
static e_ret wlan_ap_if_collectlinkstat(tdp_if * dp_if);
static e_ret wlan_ap_if_getlinkstat(tdp_if * dp_if, void **linkstat, int *size, tmask * mask);
static e_ret wlan_ap_if_getlinkstatus(tdp_if * dp_if, void **status, int *size, tmask * mask);
static e_ret wlan_ap_if_setnetcfg(tdp_if * dp_if, void *netcfg, tmask * mask);
static e_ret wlan_ap_if_connect(tdp_if * dp_if);
static e_ret wlan_ap_if_disconnect(tdp_if * dp_if);
static e_ret wlan_ap_if_collectnetstat(tdp_if * dp_if);
static e_ret wlan_ap_if_getnetstat(tdp_if * dp_if, void **netstat, int *size, tmask * mask);
static e_ret wlan_ap_if_getnetstatus(tdp_if * dp_if, void **status, int *size, tmask * mask);
static e_ret wlan_ap_if_setledstatus(tdp_if * dp_if, int status);

static void wlan_ap_if_updateledstatus(tdp_work * me, void *arg);

extern void dp_if_wlan_wps_work(tdp_work * me, void *arg);

/* Macro API definitions. */

/* Global variable declarations. */

e_ret wlan24g_ap_if_prepare(tdp_if * dp_if)
{

	sysmgr_trace_enter();

	dp_if->create = wlan_ap_if_create;
	dp_if->destroy = wlan_ap_if_destroy;
	dp_if->enable = wlan_ap_if_enable;
	dp_if->disable = wlan_ap_if_disable;
	dp_if->setlinkcfg = wlan_ap_if_setlinkcfg;
	dp_if->getlinkcfg = dpif_getlinkcfg_common;
	dp_if->link = wlan_ap_if_link;
	dp_if->unlink = wlan_ap_if_unlink;
	dp_if->collectlinkstat = wlan_ap_if_collectlinkstat;
	dp_if->getlinkstat = wlan_ap_if_getlinkstat;
	dp_if->getlinkstatus = wlan_ap_if_getlinkstatus;
	dp_if->setnetcfg = wlan_ap_if_setnetcfg;
	dp_if->getnetcfg = dpif_getnetcfg_common;
	dp_if->connect = wlan_ap_if_connect;
	dp_if->disconnect = wlan_ap_if_disconnect;
	dp_if->collectnetstat = wlan_ap_if_collectnetstat;
	dp_if->getnetstat = wlan_ap_if_getnetstat;
	dp_if->getnetstatus = wlan_ap_if_getnetstatus;
	dp_if->setledstatus = wlan_ap_if_setledstatus;

	sysmgr_trace_exit();

	return (eRET_SUCCESS);

}

e_ret wlan5g_ap_if_prepare(tdp_if * dp_if)
{

	sysmgr_trace_enter();

	dp_if->create = wlan_ap_if_create;
	dp_if->destroy = wlan_ap_if_destroy;
	dp_if->enable = wlan_ap_if_enable;
	dp_if->disable = wlan_ap_if_disable;
	dp_if->setlinkcfg = wlan_ap_if_setlinkcfg;
	dp_if->getlinkcfg = dpif_getlinkcfg_common;
	dp_if->link = wlan_ap_if_link;
	dp_if->unlink = wlan_ap_if_unlink;
	dp_if->collectlinkstat = wlan_ap_if_collectlinkstat;
	dp_if->getlinkstat = wlan_ap_if_getlinkstat;
	dp_if->getlinkstatus = wlan_ap_if_getlinkstatus;
	dp_if->setnetcfg = wlan_ap_if_setnetcfg;
	dp_if->getnetcfg = dpif_getnetcfg_common;
	dp_if->connect = wlan_ap_if_connect;
	dp_if->disconnect = wlan_ap_if_disconnect;
	dp_if->collectnetstat = wlan_ap_if_collectnetstat;
	dp_if->getnetstat = wlan_ap_if_getnetstat;
	dp_if->getnetstatus = wlan_ap_if_getnetstatus;
	dp_if->setledstatus = wlan_ap_if_setledstatus;

	sysmgr_trace_exit();
	return (eRET_SUCCESS);

}

e_ret wlan_ap_if_create(tdp_if * dp_if)
{
	sysmgr_trace_enter();

	sysmgr_trace_exit();
	return (eRET_SUCCESS);
}

e_ret wlan_ap_if_destroy(tdp_if * dp_if)
{
	sysmgr_trace_enter();

	sysmgr_trace_exit();
	return (eRET_SUCCESS);
}

e_ret wlan_ap_if_enable(tdp_if * dp_if)
{
	e_ret ret;

	sysmgr_trace_enter();

	ret = os_dep_if_up(dp_if->name);

	sysmgr_trace_exit();
	return (ret);
}

e_ret wlan_ap_if_disable(tdp_if * dp_if)
{
	e_ret ret;

	sysmgr_trace_enter();

	ret = os_dep_if_down(dp_if->name);

	sysmgr_trace_exit();
	return (ret);
}

e_ret wlan_ap_if_setlinkcfg(tdp_if * dp_if, void *linkcfg, tmask * mask)
{
	e_ret ret;
	e_bool reset;
	twlan_ap_if_linkcfg *ap_linkcfg;
	twlan_ap_if_linkcfg *new_linkcfg;
	unsigned char auth_mode;
	unsigned char enc_method;
	twlan_sec_key sec_key;

	sysmgr_trace_enter();

	reset = eBOOL_FALSE;
	if (dp_if->linkcfg == NULL) {
		ap_linkcfg = malloc(sizeof(*ap_linkcfg));
		if (ap_linkcfg == NULL) {
			sysmgr_err("malloc(%d) failed, err: %d,[%s]\n", sizeof(*ap_linkcfg), errno, strerror(errno));
			memset(mask, 0, sizeof(*mask));
			return (eRET_NO_RESOURCE);
		}
		memset(ap_linkcfg, 0, sizeof(*ap_linkcfg));
		dp_if->linkcfg = ap_linkcfg;
		dp_if->linkcfg_size = sizeof(*ap_linkcfg);
	} else {
		ap_linkcfg = (twlan_ap_if_linkcfg *) dp_if->linkcfg;
	}

	new_linkcfg = (twlan_ap_if_linkcfg *) linkcfg;

	if (mask_test_bit(mask->mask[7], eDP_IF_LINKCFG_MASK7_LOAD_CFG)) {
		/* Load config. */
		sysmgr_dbg("dp if[%s], load config.\n", dp_if->name);
		memcpy(ap_linkcfg, new_linkcfg, sizeof(*ap_linkcfg));
	}

	if (mask_test_bitmask(mask->mask[1], eWLAN_IF_LINKCFG_MASK1_WPS_ALL)) {
		if (!mask_test_bit(dp_if->attr, eDP_IF_ATTR_LINK_WPS)) {
			sysmgr_trace_exit();
			return (eRET_INVALID_STATE);
		}
		/* WPS action */
		ret = eRET_SUCCESS;
		if (mask_test_bit(mask->mask[1], eWLAN_IF_LINKCFG_MASK1_WPS_ENABLE)) {
			ap_linkcfg->wps_enable = new_linkcfg->wps_enable;
			pf_dep_wlan_set_wsc_enable(dp_if, new_linkcfg->wps_enable);
			if ((ap_linkcfg->wps_enable) && (ap_linkcfg->wps_configed)) {
				if (ap_linkcfg->wps_pin != 0) {
					pf_dep_wlan_set_wsc_vendor_pin_code(dp_if, ap_linkcfg->wps_pin);
				}
				pf_dep_wlan_set_wsc_conf_mode(dp_if, 0);
				pf_dep_wlan_set_wsc_conf_mode(dp_if, 7);
				pf_dep_wlan_set_wsc_conf_status(dp_if, 2, eBOOL_TRUE);
			} else {
				pf_dep_wlan_set_wsc_conf_mode(dp_if, 0);
			}
		}

		if (mask_test_bit(mask->mask[1], eWLAN_IF_LINKCFG_MASK1_WPS_RESET)) {
			ap_linkcfg->auth_mode = eWLAN_AUTH_MODE_WPA2PSK;
			ap_linkcfg->enc_method = eWLAN_ENC_METHOD_AES;
			/* TODO: generate random password */
			strcpy(ap_linkcfg->sec_key.wpa_psk, WLAN_WPS_RESET_WPAPSK);

			ap_linkcfg->wps_enable = eBOOL_TRUE;
			ap_linkcfg->wps_configed = eBOOL_TRUE;
			pf_dep_wlan_set_wsc_enable(dp_if, ap_linkcfg->wps_enable);
			pf_dep_wlan_set_wsc_configed(dp_if, ap_linkcfg->wps_configed);

			pf_dep_wlanap_set_sec_stuff(dp_if, ap_linkcfg->auth_mode, ap_linkcfg->enc_method,
						    &ap_linkcfg->sec_key, &reset);
			if (ap_linkcfg->wps_pin != 0) {
				pf_dep_wlan_set_wsc_vendor_pin_code(dp_if, ap_linkcfg->wps_pin);
			}
			pf_dep_wlan_set_wsc_conf_mode(dp_if, 0);
			pf_dep_wlan_set_wsc_conf_mode(dp_if, 7);
			pf_dep_wlan_set_wsc_conf_status(dp_if, 2, eBOOL_TRUE);
		}

		if (mask_test_bit(mask->mask[1], eWLAN_IF_LINKCFG_MASK1_WPS_METHOD)) {
			ret = dp_wlan_ap_start_wps(dp_if, new_linkcfg->wps_method, new_linkcfg->wps_client_pin);
		}
		sysmgr_trace_exit();
		return (ret);
	}

	if (!mask_test_bitmask(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_ALL)) {
		/* No update */
		sysmgr_trace_exit();
		return (eRET_SUCCESS);
	}

	ret = eRET_SUCCESS;
	if (mask_test_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_SSID)) {
		if (pf_dep_wlanap_set_ssid(dp_if, new_linkcfg->ssid, &reset) == eRET_SUCCESS) {
			memcpy(&ap_linkcfg->ssid, &new_linkcfg->ssid, sizeof(new_linkcfg->ssid));
		} else {
			ret = eRET_FAILURE;
			mask_clear_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_SSID);
		}
	}

	if (mask_test_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_MODE)) {
		if (pf_dep_wlanap_set_mode(dp_if, new_linkcfg->mode) == eRET_SUCCESS) {
			ap_linkcfg->mode = new_linkcfg->mode;
		} else {
			ret = eRET_FAILURE;
			mask_clear_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_MODE);
		}
	}

	if (mask_test_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_BW)) {
		if (pf_dep_wlanap_set_bw(dp_if, new_linkcfg->bw) == eRET_SUCCESS) {
			ap_linkcfg->bw = new_linkcfg->bw;
		} else {
			ret = eRET_FAILURE;
			mask_clear_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_BW);
		}
	}

	if (mask_test_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_SGI)) {
		if (pf_dep_wlanap_set_sgi(dp_if, new_linkcfg->sgi) == eRET_SUCCESS) {
			ap_linkcfg->sgi = new_linkcfg->sgi;
		} else {
			ret = eRET_FAILURE;
			mask_clear_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_SGI);
		}
	}

	if (mask_test_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_TX_PWR)) {
		if (pf_dep_wlanap_set_txpwr(dp_if, new_linkcfg->tx_pwr) == eRET_SUCCESS) {
			ap_linkcfg->tx_pwr = new_linkcfg->tx_pwr;
		} else {
			ret = eRET_FAILURE;
			mask_clear_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_TX_PWR);
		}
	}

	if (mask_test_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_CHANNEL)) {
		if (pf_dep_wlanap_set_channel(dp_if, new_linkcfg->channel, &reset) == eRET_SUCCESS) {
			ap_linkcfg->channel = new_linkcfg->channel;
		} else {
			ret = eRET_FAILURE;
			mask_clear_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_CHANNEL);
		}
	}

	if (mask_test_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_BEACON_ITV)) {
		if (pf_dep_wlanap_set_beacon_interval(dp_if, new_linkcfg->beacon_interval) == eRET_SUCCESS) {
			ap_linkcfg->beacon_interval = new_linkcfg->beacon_interval;
		} else {
			ret = eRET_FAILURE;
			mask_clear_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_BEACON_ITV);
		}
	}

	if (mask_test_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_HIDE_SSID)) {
		if (pf_dep_wlanap_set_hide_ssid(dp_if, new_linkcfg->hide_ssid) == eRET_SUCCESS) {
			ap_linkcfg->hide_ssid = new_linkcfg->hide_ssid;
		} else {
			ret = eRET_FAILURE;
			mask_clear_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_HIDE_SSID);
		}
	}

	if (mask_test_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_STA_ISOLATE)) {
		if (pf_dep_wlanap_set_sta_isolate(dp_if, new_linkcfg->sta_isolate) == eRET_SUCCESS) {
			ap_linkcfg->sta_isolate = new_linkcfg->sta_isolate;
		} else {
			ret = eRET_FAILURE;
			mask_clear_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_STA_ISOLATE);
		}
	}

	if ((mask_test_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_AUTH_MODE)) ||
	    (mask_test_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_ENC_METHOD)) ||
	    (mask_test_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_SEC_KEY))) {

		if (mask_test_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_AUTH_MODE)) {
			auth_mode = new_linkcfg->auth_mode;
		} else {
			auth_mode = ap_linkcfg->auth_mode;
		}
		if (mask_test_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_ENC_METHOD)) {
			enc_method = new_linkcfg->enc_method;
		} else {
			enc_method = ap_linkcfg->enc_method;
		}
		if (mask_test_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_SEC_KEY)) {
			sec_key = new_linkcfg->sec_key;
		} else {
			sec_key = ap_linkcfg->sec_key;
		}
		if (pf_dep_wlanap_set_sec_stuff(dp_if, auth_mode, enc_method, &sec_key, &reset) == eRET_SUCCESS) {
			ap_linkcfg->auth_mode = auth_mode;
			ap_linkcfg->enc_method = enc_method;
			ap_linkcfg->sec_key = sec_key;
			if (ap_linkcfg->auth_mode >= eWLAN_AUTH_MODE_WEPAUTO) {
				ap_linkcfg->wps_configed = eBOOL_TRUE;
			} else {
				ap_linkcfg->wps_configed = eBOOL_FALSE;
			}
			pf_dep_wlan_set_wsc_configed(dp_if, ap_linkcfg->wps_configed);

			if (mask_test_bit(dp_if->attr, eDP_IF_ATTR_LINK_WPS) && (ap_linkcfg->wps_enable)
			    && (ap_linkcfg->wps_configed)) {
				if (ap_linkcfg->wps_pin != 0) {
					pf_dep_wlan_set_wsc_vendor_pin_code(dp_if, ap_linkcfg->wps_pin);
				}
				pf_dep_wlan_set_wsc_conf_mode(dp_if, 0);
				pf_dep_wlan_set_wsc_conf_mode(dp_if, 7);
				pf_dep_wlan_set_wsc_conf_status(dp_if, 2, eBOOL_TRUE);
			} else {
				pf_dep_wlan_set_wsc_conf_mode(dp_if, 0);
			}
		} else {
			ret = eRET_FAILURE;
			mask_clear_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_AUTH_MODE);
			mask_clear_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_ENC_METHOD);
			mask_clear_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_SEC_KEY);
		}
	}

	if (mask_test_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_ACL)) {
		if (pf_dep_wlanap_set_acl(dp_if, &new_linkcfg->acl) == eRET_SUCCESS) {
			if (new_linkcfg->acl.acl_type == eWLAN_ACL_NONE) {
				ap_linkcfg->acl.acl_type = new_linkcfg->acl.acl_type;
			} else {
				ap_linkcfg->acl = new_linkcfg->acl;
			}
		} else {
			ret = eRET_FAILURE;
			mask_clear_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_ACL);
		}
	}

	if (mask_test_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_WMM_APSD_DLS)) {
		if (pf_dep_wlanap_set_wmm_apsd_dls(dp_if, new_linkcfg->wmm_apsd, new_linkcfg->wmm_dls, &reset) ==
		    eRET_SUCCESS) {
			ap_linkcfg->wmm_apsd = new_linkcfg->wmm_apsd;
			ap_linkcfg->wmm_dls = new_linkcfg->wmm_dls;
		} else {
			ret = eRET_FAILURE;
			mask_clear_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_WMM_APSD_DLS);
		}
	}

	if (mask_test_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_BG_PROTECTION)) {
		if (pf_dep_wlanap_set_bgprotection(dp_if, new_linkcfg->bg_protection) == eRET_SUCCESS) {
			ap_linkcfg->bg_protection = new_linkcfg->bg_protection;
		} else {
			ret = eRET_FAILURE;
			mask_clear_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_BG_PROTECTION);
		}
	}

	if (mask_test_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_HT_EXTCHA)) {
		if (pf_dep_wlanap_set_ht_extcha(dp_if, new_linkcfg->ht_extcha) == eRET_SUCCESS) {
			ap_linkcfg->ht_extcha = new_linkcfg->ht_extcha;
		} else {
			ret = eRET_FAILURE;
			mask_clear_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_HT_EXTCHA);
		}
	}

	if (mask_test_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_REKEY)) {
		if (pf_dep_wlanap_set_rekey(dp_if, new_linkcfg->rekey, &reset) == eRET_SUCCESS) {
			ap_linkcfg->rekey = new_linkcfg->rekey;
		} else {
			ret = eRET_FAILURE;
			mask_clear_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_REKEY);
		}
	}

	if (mask_test_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_RTSTHRESHOLD)) {
		if (pf_dep_wlanap_set_rtsthreshold(dp_if, new_linkcfg->rtsthreshold) == eRET_SUCCESS) {
			ap_linkcfg->rtsthreshold = new_linkcfg->rtsthreshold;
		} else {
			ret = eRET_FAILURE;
			mask_clear_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_RTSTHRESHOLD);
		}
	}

	if (mask_test_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_FRAGTHRESHOLD)) {
		if (pf_dep_wlanap_set_fragthreshold(dp_if, new_linkcfg->fragthreshold) == eRET_SUCCESS) {
			ap_linkcfg->fragthreshold = new_linkcfg->fragthreshold;
		} else {
			ret = eRET_FAILURE;
			mask_clear_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_FRAGTHRESHOLD);
		}
	}

	if (mask_test_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_DTIMPERIOD)) {
		if (pf_dep_wlanap_set_dtimperiod(dp_if, new_linkcfg->dtimperiod) == eRET_SUCCESS) {
			ap_linkcfg->dtimperiod = new_linkcfg->dtimperiod;
		} else {
			ret = eRET_FAILURE;
			mask_clear_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_DTIMPERIOD);
		}
	}

	if (mask_test_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_TXBURST)) {
		if (pf_dep_wlanap_set_txburst(dp_if, new_linkcfg->txburst) == eRET_SUCCESS) {
			ap_linkcfg->txburst = new_linkcfg->txburst;
		} else {
			ret = eRET_FAILURE;
			mask_clear_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_TXBURST);
		}
	}

	if (mask_test_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_PKTAGGREGATE)) {
		if (pf_dep_wlanap_set_pktaggregate(dp_if, new_linkcfg->pktaggregate) == eRET_SUCCESS) {
			ap_linkcfg->pktaggregate = new_linkcfg->pktaggregate;
		} else {
			ret = eRET_FAILURE;
			mask_clear_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_PKTAGGREGATE);
		}
	}

	if (mask_test_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_GREENAP)) {
		if (pf_dep_wlanap_set_greenap(dp_if, new_linkcfg->greenap) == eRET_SUCCESS) {
			ap_linkcfg->greenap = new_linkcfg->greenap;
		} else {
			ret = eRET_FAILURE;
			mask_clear_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_GREENAP);
		}
	}

	if (mask_test_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_GREENFIELD)) {
		if (pf_dep_wlanap_set_greenfied(dp_if, new_linkcfg->greenfield) == eRET_SUCCESS) {
			ap_linkcfg->greenfield = new_linkcfg->greenfield;
		} else {
			ret = eRET_FAILURE;
			mask_clear_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_GREENFIELD);
		}
	}

	if (mask_test_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_APENABLE)) {
		if (pf_dep_wlanap_set_radio_on(dp_if, new_linkcfg->radio_on) == eRET_SUCCESS) {
			ap_linkcfg->radio_on = new_linkcfg->radio_on;
		} else {
			ret = eRET_FAILURE;
			mask_clear_bit(mask->mask[0], eWLAN_AP_IF_LINKCFG_MASK0_APENABLE);
		}
	}

	if (mask_test_bit(mask->mask[7], eDP_IF_LINKCFG_MASK7_LOAD_CFG)) {
		/* Update WPS Parameter. */
		if (mask_test_bit(dp_if->attr, eDP_IF_ATTR_LINK_WPS) && (ap_linkcfg->wps_enable)
		    && (ap_linkcfg->wps_configed)) {
			if (ap_linkcfg->wps_pin != 0) {
				pf_dep_wlan_set_wsc_vendor_pin_code(dp_if, ap_linkcfg->wps_pin);
			}
			pf_dep_wlan_set_wsc_conf_mode(dp_if, 7);
			pf_dep_wlan_set_wsc_conf_status(dp_if, 2, eBOOL_FALSE);
		} else {
			pf_dep_wlan_set_wsc_conf_mode(dp_if, 0);
		}
	} else {
		if (reset == eBOOL_TRUE) {
			ret = pf_dep_wlanap_reset(dp_if);
		}
	}

	sysmgr_trace_exit();
	return (ret);
}

e_ret wlan_ap_if_link(tdp_if * dp_if)
{
	tdp_work update_led_status;

	sysmgr_trace_enter();

	if (dp_if->led.led != NULL) {
		/* Set to LED Init Stat. */
		dp_if_set_led_status(dp_if, eLED_STATUS_INIT);

		/* Add to datapath work task for LED update */
		update_led_status.arg = dp_if;
		sprintf(update_led_status.name, "%s" DP_IF_LED_WORK_SUBFIX, dp_if->name);
		update_led_status.work = wlan_ap_if_updateledstatus;

		dp_task_add_work(dp_if->data_paths, &update_led_status);
	}

	sysmgr_trace_exit();
	return (eRET_SUCCESS);
}

e_ret wlan_ap_if_unlink(tdp_if * dp_if)
{
	tdp_if *br_if;
	tdata_paths *dp;
	tdp_work update_led_status;

	sysmgr_trace_enter();

	if (dp_if->led.led != NULL) {
		/* Delete  LED update from datapath work task. */
		update_led_status.arg = dp_if;
		sprintf(update_led_status.name, "%s" DP_IF_LED_WORK_SUBFIX, dp_if->name);
		update_led_status.work = wlan_ap_if_updateledstatus;

		dp_task_del_work(dp_if->data_paths, &update_led_status);

		/* Turn off LEDs. */
		dp_if_set_led_status(dp_if, eLED_STATUS_SIGNAL_NONE);
	}

	if (((dp = dp_if->data_paths) != NULL) && ((br_if = dp_if->data_if) != NULL) &&
	    (br_if->type == eDP_IF_TYPE_BRIDGE)) {
		bridge_remove_member_if(dp, br_if, dp_if);
	}

	sysmgr_trace_exit();
	return (eRET_SUCCESS);
}

e_ret wlan_ap_if_collectlinkstat(tdp_if * dp_if)
{
	sysmgr_trace_enter();

	sysmgr_trace_exit();
	return (eRET_SUCCESS);
}

e_ret wlan_ap_if_getlinkstat(tdp_if * dp_if, void **linkstat, int *size, tmask * mask)
{
	sysmgr_trace_enter();

	sysmgr_trace_exit();
	return (eRET_SUCCESS);
}

e_ret wlan_ap_if_getlinkstatus(tdp_if * dp_if, void **status, int *size, tmask * mask)
{

	e_ret ret = eRET_SUCCESS;
	twlan_ap_if_link_status *clients;

	sysmgr_trace_enter();

	pf_dep_wlanap_get_linkstatus(dp_if, &clients);
	if (clients == NULL) {
		clients = malloc(sizeof(*clients));
		if (clients != NULL) {
			clients->counter = 0;
		} else {
			ret = eRET_NO_RESOURCE;
		}
	}

	*status = clients;
	if (*status == NULL) {
		*size = 0;
	} else {
		clients->wps_status = dp_if->wps.status;
		*size = sizeof(twlan_ap_if_link_status) + clients->counter * sizeof(twlan_ap_if_link_entry);
	}

	sysmgr_trace_exit();
	return (ret);
}

e_ret wlan_ap_if_setnetcfg(tdp_if * dp_if, void *netcfg, tmask * mask)
{
	sysmgr_trace_enter();

	sysmgr_trace_exit();
	return (eRET_SUCCESS);
}

e_ret wlan_ap_if_connect(tdp_if * dp_if)
{
	sysmgr_trace_enter();

	sysmgr_trace_exit();
	return (eRET_SUCCESS);
}

e_ret wlan_ap_if_disconnect(tdp_if * dp_if)
{
	sysmgr_trace_enter();

	sysmgr_trace_exit();
	return (eRET_SUCCESS);
}

e_ret wlan_ap_if_collectnetstat(tdp_if * dp_if)
{
	sysmgr_trace_enter();

	sysmgr_trace_exit();
	return (eRET_SUCCESS);
}

e_ret wlan_ap_if_getnetstat(tdp_if * dp_if, void **netstat, int *size, tmask * mask)
{
	sysmgr_trace_enter();

	sysmgr_trace_exit();
	return (eRET_SUCCESS);
}

e_ret wlan_ap_if_getnetstatus(tdp_if * dp_if, void **status, int *size, tmask * mask)
{
	e_ret ret;

	sysmgr_trace_enter();

	ret = dpif_getnetstatus_common(dp_if, (void *)status, size);

	sysmgr_trace_exit();
	return (ret);
}

e_ret wlan_ap_if_setledstatus(tdp_if * dp_if, int status)
{
	int last_status;
	unsigned char led_opt;

	sysmgr_trace_enter();

	sysmgr_dbg("IF[%s] Set LED Status -> [%d], \n", dp_if->name, status);

	last_status = dp_if->led.status;
	switch (status) {
	case eLED_STATUS_SIGNAL_NONE:
	case eLED_STATUS_SIGNAL_LOW:
	case eLED_STATUS_SIGNAL_NORMAL:
	case eLED_STATUS_SIGNAL_HIGH:
		dp_if->led.counter = 2;
		break;
	case eLED_STATUS_SCAN:
		dp_if->led.counter = 30;
		break;

	case eLED_STATUS_WPS_PROCESS:
		dp_if->led.counter = 120;
		break;

	case eLED_STATUS_WPS_SUCCESS:
		dp_if->led.counter = 6;
		break;
	case eLED_STATUS_WPS_FAIL:
		dp_if->led.counter = 6;
		break;

	case eLED_STATUS_WPS_OVERLAP:
		dp_if->led.counter = 6;
		break;

	case eLED_STATUS_INIT:
		if (last_status == eLED_STATUS_SIGNAL_NONE) {
			dp_if->led.counter = 1;
			if (dp_if->type == eDP_IF_TYPE_WLAN24G_AP) {
				led_opt = eLED_OPT_SET_24G_SIGNAL_NONE;
			} else {
				led_opt = eLED_OPT_SET_5G_SIGNAL_NONE;
			}
			sa_led_opt(dp_if->led.led, led_opt);
		}
		sysmgr_trace_exit();
		return (eRET_SUCCESS);
		break;

	default:
		/* Do Nothing */
		sysmgr_trace_exit();
		return (eRET_INVALID_ARG);
	}
	dp_if->led.status = status;

	if (last_status != status) {
		if (dp_if->type == eDP_IF_TYPE_WLAN24G_AP) {
			led_opt = eLED_OPT_SET_24G_SIGNAL_NONE + status;
		} else {
			led_opt = eLED_OPT_SET_5G_SIGNAL_NONE + status;
		}
		sa_led_opt(dp_if->led.led, led_opt);
	}

	sysmgr_trace_exit();
	return (eRET_SUCCESS);
}

void wlan_ap_if_updateledstatus(tdp_work * me, void *arg)
{
	unsigned char status;
	tdp_if *dp_if = (tdp_if *) arg;
	twlan_ap_if_linkcfg *ap_linkcfg;

	sysmgr_trace_enter();

	sysmgr_dbg("IF[%s], LED Status[%d], Counter: %d\n", dp_if->name, dp_if->led.status, dp_if->led.counter);
	if (dp_if->led.counter-- <= 0) {
		ap_linkcfg = dp_if->linkcfg;
		/* Update LED status. */
		if ((ap_linkcfg != NULL) && (ap_linkcfg->radio_on)) {
			status = eLED_STATUS_SIGNAL_HIGH;
		} else {
			status = eLED_STATUS_SIGNAL_NONE;
		}
		/* update status */
		if (dp_if->led.status != status) {
			dp_if_set_led_status(dp_if, status);
		}
		dp_if->led.counter = 2;
	}

	sysmgr_trace_exit();
}

e_ret dp_wlan_ap_start_wps(tdp_if * dp_if, unsigned char wps_method, unsigned long pin)
{

	tdp_work wlan_wps_work;
	twlan_ap_if_linkcfg *linkcfg;

	sysmgr_trace_enter();

	linkcfg = (twlan_ap_if_linkcfg *) dp_if->linkcfg;
	if ((linkcfg == NULL) || (!linkcfg->wps_enable) || (!linkcfg->wps_configed)) {
		sysmgr_trace_exit();
		return (eRET_INVALID_STATE);
	}

	if ((wps_method != eWLAN_WPS_DPID_PBC) && (wps_method != eWLAN_WPS_DPID_PIN)) {
		sysmgr_trace_exit();
		return (eRET_INVALID_ARG);
	}

	if ((wps_method == eWLAN_WPS_DPID_PIN) && (pin == 0)) {
		sysmgr_trace_exit();
		return (eRET_INVALID_ARG);
	}

	pf_dep_wlan_set_wsc_mode(dp_if, wps_method);
	if (wps_method == eWLAN_WPS_DPID_PIN) {
		pf_dep_wlan_set_wsc_pin_code(dp_if, pin);
	}
	pf_dep_wlan_set_wsc_get_conf(dp_if, eBOOL_TRUE);

	dp_if->wps.counter = 0;

	dp_if_set_led_status(dp_if, eLED_STATUS_WPS_PROCESS);

	wlan_wps_work.arg = dp_if;
	sprintf(wlan_wps_work.name, "%s" DP_IF_WPS_WORK_SUBFIX, dp_if->name);
	wlan_wps_work.work = dp_if_wlan_wps_work;

	dp_task_add_work(dp_if->data_paths, &wlan_wps_work);
	sysmgr_trace_exit();
	return (eRET_SUCCESS);
}
